//           Copyright Daniel Goertzen 2007.
//  Distributed under the Boost Software License, Version 1.0.
//     (See accompanying file LICENSE_1_0.txt or copy at
//           http://www.boost.org/LICENSE_1_0.txt)

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/TestFactoryRegistry.h>



#include "et.hpp"
#include <sstream>
#include <string>


using namespace eipp;
//using namespace std;

// void checkoutput(et x,std::string out)
// {
// 	ostringstream ss;
// 	ss << x;
// 	CPPUNIT_ASSERT_EQUAL(  out,ss.str()  );
// }

// stream and unstream the specified term
// void restream(et a,std::string out)
// {
// 	ostringstream os;
// 	et_to_etfstream(os,a);
	
// 	istringstream is(os.str());
// 	et x=etfstream_to_et(is);
// 	checkoutput(x,out);
// }



class mytest: public CppUnit::TestFixture
{

	CPPUNIT_TEST_SUITE(mytest);

//CPPUNIT_TEST(selfstream);
	CPPUNIT_TEST(testint);
 	CPPUNIT_TEST(testnative);
 	CPPUNIT_TEST(testempty);
 	CPPUNIT_TEST(testpack);
 	CPPUNIT_TEST(testatom);
 	CPPUNIT_TEST(teststring);
 	CPPUNIT_TEST(teststream);
// 	CPPUNIT_TEST(testetf);

	CPPUNIT_TEST_SUITE_END();

public:
	void setUp()
		{
		}
	
	void tearDown()
		{
		}

	void testint()

		{ // test int
			et x=4;
			int a=x;
			CPPUNIT_ASSERT(a==4);
		}

	void testnative()
		{ // test native type strength
			et x=4;
			try
			{
				long a=x;
				CPPUNIT_ASSERT(0);
			}
			catch(bad_match)
			{}
		}

	void testempty()
		{ // empty list
			et x=list();
			list_t &a=x;
		    CPPUNIT_ASSERT(a.size()==0);
		}

	void testpack()
		{ // list pack/unpack
			et x=list(1,2,3);

			int a,b,c;
			unlist(a,b,c)=x;
			CPPUNIT_ASSERT(a==1);
			CPPUNIT_ASSERT(b==2);
			CPPUNIT_ASSERT(c==3);

			unlist(a,b,c)=list(4,5,6);
			CPPUNIT_ASSERT(a==4);
			CPPUNIT_ASSERT(b==5);
			CPPUNIT_ASSERT(c==6);

			try
			{
				unlist(a,b,c)=list(1,2,3,4);
				CPPUNIT_ASSERT(0);
			}
			catch(bad_match){}

			// nested
			x=list(7,list(8,9));
			et y;
			unlist(a,y)=x;
			unlist(b,c)=y;
			CPPUNIT_ASSERT(a==7);
			CPPUNIT_ASSERT(b==8);
			CPPUNIT_ASSERT(c==9);
		}
	// not testing tuple because it's from the same source

	// atoms
	void testatom()
		{
			et x="hi";
			atom_t a=x;
			CPPUNIT_ASSERT(a=="hi");

			x=atom_t("bye");
			a=x;
			CPPUNIT_ASSERT(a=="bye");
		}

	// strings
	void teststring()
		{
			et x=string_t("hi");
			string_t a=x;
			CPPUNIT_ASSERT(a=="hi");
		}
		
// 	// stream insertion
	void teststream()
		{
			et x=list(1,2,tuple(3.14,"hi"));
			std::cout << x << std::endl;
		}

// 	// etf serialization/deserialization
// 	void testetf()
// 		{
// 			ostringstream s1,s2;
// 			et x=list(1,2,string_t("puppies"),tuple(3.14,"hi"),list(),string_t("kittens"));

// 			//[1, 2, "puppies", {3.140000, hi}, [], [] | "kittens"]

// 			std::cout << x << std::endl;
// 			s1 << x;

// 			et y=term_to_binary(x);
// 			std::cout << y << std::endl;

// 			et z=binary_to_term(y);
// 			std::cout << z << std::endl;
// 			s2 << z;
			
// 			CPPUNIT_ASSERT(s1.str()==s2.str());
			
// 		}

};
CPPUNIT_TEST_SUITE_REGISTRATION( mytest );

int main()
{
	CppUnit::TextUi::TestRunner runner;
	CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
	runner.addTest( registry.makeTest() );
	if(runner.run())
		return 0;
	else
		return 1;
}

